using EnvDTE;
using Microsoft.VisualStudio.Shell;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace VSIXProject_First
{
    /// <summary>
    /// Command handler
    /// </summary>
    internal sealed class Command
    {
        /// <summary>
        /// Command ID.
        /// </summary>
        public const int CommandId = 0x0100;
        /// <summary>
        /// Command menu group (command set GUID).
        /// </summary>
        public static readonly Guid CommandSet = new Guid("c9da6df7-01c5-471c-b9df-93f9082e9d8e");

        public static readonly Guid CommandOpen = new Guid("0b942b75-7f0b-4db0-a10e-6e067fa3a673");
        /// <summary>
        /// VS Package that provides this command, not null.
        /// </summary>
        private readonly Package package;

        private int baseMRUID = 0x200;
        private Dictionary<int, string> dicPath = new Dictionary<int, string>();
        private string SolutionPath = string.Empty;//解决方案所在的目录
        /// <summary>
        /// Initializes a new instance of the <see cref="Command"/> class.
        /// Adds our command handlers for menu (commands must exist in the command table file)
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        /// <param name="commandService">Command service to add command to, not null.</param>
        private Command(Package package, OleMenuCommandService commandService)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            this.package = package ?? throw new ArgumentNullException(nameof(package));
            commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));
            //添加打开项目命令
            //this.InitMRUMenu(commandService);
            //添加打开视图命令
            //var menuCommandID = new CommandID(CommandSet, 0x0120);
            //var menuItem = new OleMenuCommand(ExecuteOpenView, menuCommandID);
            //menuItem.BeforeQueryStatus += Controller_BeforeQueryStatus;
            //commandService.AddCommand(menuItem);
            //添加打开JS命令
            var menuCommandJsID = new CommandID(CommandSet, 0x0140);
            var menuJsItem = new OleMenuCommand(ExecuteOpenJs, menuCommandJsID);
            menuJsItem.BeforeQueryStatus += Cshtml_BeforeQueryStatus;
            commandService.AddCommand(menuJsItem);
            //添加OpenAction
            var menuCommandActionID = new CommandID(CommandSet, 0x1110);
            var menuCommandAction = new OleMenuCommand(ExecuteAction, menuCommandActionID);
            commandService.AddCommand(menuCommandAction);


            //------------vs2015中cshtml页面的右键菜单和2017中不一样，要重新添加菜单----------
            //var menuCommandJsID2 = new CommandID(CommandOpen, 0x0140);
            //var menuJsItem2 = new OleMenuCommand(ExecuteOpenJs, menuCommandJsID2);
            ////menuJsItem2.BeforeQueryStatus += Cshtml_BeforeQueryStatus;
            //commandService.AddCommand(menuJsItem2);

            ////添加OpenAction
            //var menuCommandActionID2015 = new CommandID(CommandOpen, 0x1110);
            //var menuCommandAction2015 = new OleMenuCommand(ExecuteAction, menuCommandActionID2015);
            //commandService.AddCommand(menuCommandAction2015);
        }

        private void InitMRUMenu(OleMenuCommandService mcs)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
            if (dte == null)
                return;
            //string Path = dte.ActiveDocument.Path;
            //string solName = dte.Solution.FileName;
            //解决方案名称
            string SolutionFileName = dte.Solution.FileName;
            if (SolutionFileName.ToLower() != "LeiliTech.ABP.MES".ToLower())
                return;
            SolutionPath = SolutionFileName.Substring(0, SolutionFileName.LastIndexOf("\\")).ToUpper();
            string workspace = SolutionPath.Substring(0, SolutionPath.LastIndexOf("\\"));
            var listPath = Directory.GetDirectories(workspace).Where(t => t.Contains("PDRZ.Integration") && !t.Contains("作废") && !t.Contains(SolutionPath)).ToList();

            for (int i = 0; i < listPath.Count; i++)
            {
                var cmdID = new CommandID(CommandSet, baseMRUID + i);
                OleMenuCommand mc = new OleMenuCommand(new EventHandler(OnMRUExec), cmdID);
                string name = listPath[i].Replace(workspace + "\\PDRZ.Integration", "");
                mc.Text = name == "" ? "产品" : name;
                dicPath.Add(i, listPath[i]);
                mcs.AddCommand(mc);
                //vs2015
                var cmdID2015 = new CommandID(CommandOpen, baseMRUID + i);
                OleMenuCommand mc2015 = new OleMenuCommand(new EventHandler(OnMRUExec), cmdID2015);
                mc2015.Text = name == "" ? "产品" : name;
                mcs.AddCommand(mc2015);
            }
        }

        private void OnMRUExec(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            var menuCommand = sender as OleMenuCommand;
            if (null != menuCommand)
            {
                DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
                if (dte == null)
                    return;
                string DocumentFullName = dte.ActiveDocument.FullName.ToUpper();//获取到的活动文档路径大小写忽大忽小。。。
                //File.AppendAllText("D:\\logvsix.txt", $"DocumentFullName：{DocumentFullName}\r\n");
                int ItemIndex = menuCommand.CommandID.ID - this.baseMRUID;
                string TargetPath = dicPath[ItemIndex];
                string oldPath = DocumentFullName.Replace(SolutionPath, TargetPath);
                //if (!File.Exists(oldPath))
                //{
                //    System.Windows.Forms.MessageBox.Show("文件不存在");
                //    return;
                //}
                string cmd = "File.OpenFile";
                string args = $"{oldPath}";
                dte.ExecuteCommand(cmd, args);

                // This is the guid and id for the Tools.DiffFiles command
                //对比文件命令
                //string diffFilesCmd = "{5D4C0442-C0A2-4BE8-9B4D-AB1C28450942}";
                //int diffFilesId = 256;
                //object args = $"\"{DocumentFullName}\" \"{oldPath}\"";
                //object args2 = $"\"{DocumentFullName}\" \"{oldPath}\"";
                //dte.Commands.Raise(diffFilesCmd, diffFilesId, ref args, ref args2);
            }
        }

        private void ExecuteAction(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
            if (dte == null)
                return;
            string url = System.Windows.Forms.Clipboard.GetText();
            if (!string.IsNullOrEmpty(url))
            {
                url = url.Replace(@"http://", "");
                string[] arr = url.Split('/');
                if (arr.Length >= 3)
                {
                    string area = "";
                    string controller = "";
                    string action = "";
                    if (arr.Length == 4)
                    {
                        area = arr[1];
                        controller = arr[2] + "Controller.cs";
                        action = arr[3];
                    }
                    string path = SolutionPath + @"\00_根目录\LeiliTech.MES.Web\Areas\" + area + @"\Controllers";
                    string fileName = controller;
                    string[] files = Directory.GetFiles(path, controller, SearchOption.TopDirectoryOnly);
                    if (files.Length > 0)
                    {
                        dte.ExecuteCommand("File.OpenFile", files[0]);
                        TextSelection ts = dte.ActiveDocument.Selection as TextSelection;
                        action.Replace("#", "");
                        if (action.IndexOf('?') > -1)
                        {
                            action = action.Substring(0, action.IndexOf('?'));
                        }
                        ts.FindText(action);
                    }
                    else
                        System.Windows.Forms.MessageBox.Show("未找到匹配的Action");
                }
                else
                    System.Windows.Forms.MessageBox.Show("不匹配的url");
            }
            else
                System.Windows.Forms.MessageBox.Show("请先复制url");
        }

        private void ExecuteOpenView(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
            if (dte == null)
                return;
            TextSelection ts = dte.ActiveDocument.Selection as TextSelection;
            ts.SelectLine();
            //可以获取选中的函数
            //var fun = ts.ActivePoint.CodeElement[vsCMElement.vsCMElementFunction] as CodeFunction;
            string viewPath = ts.Text;
            string pathCshtml = Regex.Match(viewPath, @"~.+\w+.cshtml").Value;
            if (!string.IsNullOrEmpty(pathCshtml))
            {
                string DocumentFullName = dte.ActiveDocument.FullName;
                DocumentFullName = DocumentFullName.Substring(0, DocumentFullName.IndexOf(@"PDRZ.IntegrationController",StringComparison.OrdinalIgnoreCase));
                pathCshtml = DocumentFullName + pathCshtml.Replace("~", @"PDRZ.IntegrationSchool");
                pathCshtml = pathCshtml.Replace(@"/", @"\");
                string cmd = "File.OpenFile";
                string args = $"{pathCshtml}";
                dte.ExecuteCommand(cmd, args);
            }
        }

        private void Controller_BeforeQueryStatus(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            OleMenuCommand menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
                if (dte == null)
                    return;
                var fileName = dte.ActiveDocument.FullName;
                if (fileName.EndsWith("Controller.cs", StringComparison.OrdinalIgnoreCase))
                    menuCommand.Visible = true;
                else
                    menuCommand.Visible = false;
            }
        }

        private void ExecuteOpenJs(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
            if (dte == null)
                return;
            TextSelection ts = dte.ActiveDocument.Selection as TextSelection;
            ts.SelectLine();
            string viewPath = ts.Text;
            string pathCshtml = Regex.Match(viewPath, @"~.+\w+.js").Value;
            if (!string.IsNullOrEmpty(pathCshtml))
            {
                string DocumentFullName = dte.ActiveDocument.FullName;
                string f = "LeiliTech.MES.Web";
                DocumentFullName = DocumentFullName.Substring(0, DocumentFullName.IndexOf(f, StringComparison.OrdinalIgnoreCase) + f.Length);
                pathCshtml = DocumentFullName + pathCshtml.Replace("~", "");
                pathCshtml = pathCshtml.Replace(@"/", @"\");
                string cmd = "File.OpenFile";
                string args = $"{pathCshtml}";
                dte.ExecuteCommand(cmd, args);
            }
        }

        private void Cshtml_BeforeQueryStatus(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            OleMenuCommand menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
                if (dte == null)
                    return;
                var fileName = dte.ActiveDocument.FullName;
                if (fileName.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase))
                    menuCommand.Visible = true;
                else
                    menuCommand.Visible = false;
            }
        }

        /// <summary>
        /// Gets the instance of the command.
        /// </summary>
        public static Command Instance
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the service provider from the owner package.
        /// </summary>
        //private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider
        //{
        //    get
        //    {
        //        return this.package;
        //    }
        //}

        /// <summary>
        /// Initializes the singleton instance of the command.
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        //public static async Task InitializeAsync(AsyncPackage package)
        //{
        //    // Switch to the main thread - the call to AddCommand in Command's constructor requires
        //    // the UI thread.
        //    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);

        //    OleMenuCommandService commandService = await package.GetServiceAsync((typeof(IMenuCommandService))) as OleMenuCommandService;
        //    Instance = new Command(package, commandService);
        //}

        public static void Initialize(Package package, OleMenuCommandService commandService)
        {
            // switch to the main thread - the call to addcommand in command's constructor requires
            // the ui thread.
            //await threadhelper.joinabletaskfactory.switchtomainthreadasync(package.disposaltoken);

            //OleMenuCommandService commandservice = gets((typeof(imenucommandservice))) as olemenucommandservice;
            Instance = new Command(package, commandService);
        }
    }
}
